//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.1.0
#include "Ring_Buffer.h"
#include <string.h>

/*环形缓冲区结构体*/
typedef struct
{
    volatile short Write_Mutex;//写锁
    volatile short Read_Mutex; //读锁
    unsigned char* Buffer;     //FIFO缓存
    unsigned short Buffer_Size;//FIFO缓存大小
    unsigned short Data_Size;  //有效数据个数
    unsigned short Write_Index;//写索引
    unsigned short Read_Index; //读索引
}WHT_Handle_t;

#define WHT_Ring_Buffer_Hadnle    ((WHT_Handle_t*)handle)

/*初始化环形缓冲区*/
static void WHT_Init(WHT_Ring_Buffer_Handle_t* handle, unsigned char* buffer, unsigned short buffer_size)
{
    *handle = buffer_size < sizeof(WHT_Handle_t) ? (WHT_Ring_Buffer_Handle_t)0 : (WHT_Ring_Buffer_Handle_t)buffer;
    if (*handle == (WHT_Ring_Buffer_Handle_t)0)
        return;
    else
    {
        WHT_Handle_t* WHT_Handle = (WHT_Handle_t*)buffer;

        WHT_Handle->Write_Mutex = 0;
        WHT_Handle->Read_Mutex = 0;
        WHT_Handle->Buffer = buffer + sizeof(WHT_Handle_t);
        WHT_Handle->Buffer_Size = buffer_size - sizeof(WHT_Handle_t);
        WHT_Handle->Data_Size = 0;
        WHT_Handle->Write_Index = 0;
        WHT_Handle->Read_Index = 0;
    }
}
/*获取环形缓冲区有效数据大小*/
static unsigned short WHT_Ring_Buffer_Get_Data_Size(const WHT_Ring_Buffer_Handle_t handle)
{
    return WHT_Ring_Buffer_Hadnle->Data_Size;
}
/*获取环形缓冲区空闲大小*/
static unsigned short WHT_Ring_Buffer_Get_Idle_Size(const WHT_Ring_Buffer_Handle_t handle)
{
    return (WHT_Ring_Buffer_Hadnle->Buffer_Size - WHT_Ring_Buffer_Hadnle->Data_Size);
}
/*FIFO写环形缓冲区,返回写入的个数*/
static unsigned short WHT_Ring_Buffer_Write(const WHT_Ring_Buffer_Handle_t handle, const unsigned char* input_buffer, unsigned short length)
{
    unsigned short Write_Count;

    if (WHT_Ring_Buffer_Hadnle->Write_Mutex != 0)//写锁打开则不写入
        return 0;
    else
        WHT_Ring_Buffer_Hadnle->Write_Mutex = 1;

    Write_Count = WHT_Ring_Buffer_Get_Idle_Size(handle);
    Write_Count = Write_Count > length ? length : Write_Count;

    for (unsigned short i = 0; i < Write_Count; i++)
    {
        WHT_Ring_Buffer_Hadnle->Buffer[WHT_Ring_Buffer_Hadnle->Write_Index] = input_buffer[i];
        WHT_Ring_Buffer_Hadnle->Write_Index = (WHT_Ring_Buffer_Hadnle->Write_Index + 1) % WHT_Ring_Buffer_Hadnle->Buffer_Size;
    }
    WHT_Ring_Buffer_Hadnle->Data_Size += Write_Count;
    WHT_Ring_Buffer_Hadnle->Write_Mutex = 0;
    return Write_Count;
}
/*FIFO读环形缓冲区,返回读取的个数*/
static unsigned short WHT_Ring_Buffer_Read(const WHT_Ring_Buffer_Handle_t handle, unsigned char* ontput_buffer, unsigned short length)
{
    unsigned short Read_Count;

    if (WHT_Ring_Buffer_Hadnle->Read_Mutex != 0)
        return 0;
    else
        WHT_Ring_Buffer_Hadnle->Read_Mutex = 1;

    Read_Count = WHT_Ring_Buffer_Hadnle->Data_Size > length ? length : WHT_Ring_Buffer_Hadnle->Data_Size;
    for (unsigned short i = 0; i < Read_Count; i++)
    {
        ontput_buffer[i] = WHT_Ring_Buffer_Hadnle->Buffer[WHT_Ring_Buffer_Hadnle->Read_Index];
        WHT_Ring_Buffer_Hadnle->Read_Index = (WHT_Ring_Buffer_Hadnle->Read_Index + 1) % WHT_Ring_Buffer_Hadnle->Buffer_Size;
    }
    WHT_Ring_Buffer_Hadnle->Data_Size -= Read_Count;
    WHT_Ring_Buffer_Hadnle->Read_Mutex = 0;
    return Read_Count;
}

/*全局常量*/
const WHT_Ring_Buffer_t WHT_Ring_Buffer = 
{
    .WHT_Register      = WHT_Init,
    .WHT_Get_Data_Size = WHT_Ring_Buffer_Get_Data_Size,
    .WHT_Get_Idle_Size = WHT_Ring_Buffer_Get_Idle_Size,
    .WHT_Write         = WHT_Ring_Buffer_Write,
    .WHT_Read          = WHT_Ring_Buffer_Read,
};
